﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Threading;
using QDT.Cache;
using QDT.Common;
using QDT.Core;
using QDT.Core.Deals;
using QDT.Core.Members;
using QDT.Core.Projects;

namespace QDT.Services.Projects
{
    public class ProjectService : ServiceBase, IProjectService
    {
        #region Implementation of IProjectService

        /// <summary>
        /// 新增标
        /// </summary>
        /// <param name="project">项目对象</param>
        /// <param name="extends">扩展属性集合 </param>
        /// <returns></returns>
        public Project CreateProject(Project project , NameValueCollection extends) {

            var feilds = DbProvider.D<ProjectFeild>().Where(x => x.TypeID == project.TypeID);
            var attrs = new List<ProjectExtend>();
            
            foreach (var feild in feilds)
            {
                if (extends[project.TypeID + "_" + feild.Name] != null)
                {
                    attrs.Add(new ProjectExtend
                    {
                        FeildID = feild.ID,
                        Value = extends[project.TypeID + "_" + feild.Name]
                    });
                }
            }

            project.ExtendAttributes = attrs;

            DbProvider.Add(project);
            DbProvider.SaveChanges();

            return project;
        }

        public Project GetProject(int projectid)
        {
            const string key = "Project/GetProject/U_{0}/";
            var cache = QDTCache.GetCacheService();
            var project = cache.RetrieveObject(key.FormatWith(projectid.ToString(CultureInfo.InvariantCulture).Hash())) as Project;
            if (project == null)
            {
                project = DbProvider.NoTrack<Project>().FirstOrDefault(x => x.ID == projectid);
                cache.AddObject(key.FormatWith(projectid.ToString(CultureInfo.InvariantCulture).Hash()), project, 3);
            }
            return project;
        }

        /// <summary>
        /// 更新项目信息
        /// </summary>
        /// <param name="project">项目对象</param>
        /// <param name="extends">项目的扩展属性键值对集合</param>
        public void UpdateProject(Project project, NameValueCollection extends) {

            var feilds = DbProvider.D<ProjectFeild>().Where(x => x.TypeID == project.TypeID);

            foreach (var feild in feilds)
            {
                if (extends[project.TypeID + "_" + feild.Name] == null) continue;

                var oldExtend = project.ExtendAttributes.FirstOrDefault(x => x.FeildID == feild.ID);

                if (oldExtend != null)
                {
                    oldExtend.Value = extends[project.TypeID+"_"+feild.Name];
                }
                else
                {
                    project.ExtendAttributes.Add(new ProjectExtend
                    {
                        FeildID = feild.ID,
                        Value = extends[project.TypeID+"_"+feild.Name]
                    });
                }
            }

            DbProvider.Update(project);
            DbProvider.SaveChanges();
        }

        /// <summary>
        /// 从回收站恢复项目类型
        /// </summary>
        /// <param name="id">项目的ID数组</param>
        public void RestoreProject(int[] id) {

            foreach (var i in id)
            {

                var project = DbProvider.GetByID<Project>(i);

                if (project == null) continue;

                project.IsDelete = false;
            }

            DbProvider.SaveChanges();
        }

        /// <summary>
        /// 删除项目到回收站
        /// </summary>
        /// <param name="id">项目的ID数组</param>
        public void DeleteProject(int[] id) {

            foreach (var i in id) {

                var project = DbProvider.GetByID<Project>(i);

                //只有处于等待审核中和流标状态的项目才能被删除
                if (project.Status != ProjectStatus.Wait && project.Status != ProjectStatus.Bad) throw new ProjectException(ProjectException.NotDeleteStatus, project);

                project.IsDelete = true;

            }

            DbProvider.SaveChanges();
        }

        /// <summary>
        /// 从回收站永久性删除项目
        /// </summary>
        /// <param name="id">项目的ID数组</param>
        public void ForeverDeleteProject(int[] id) {
            if (id == null) return;
            foreach (var did in id)
            {

                var id1 = did;

                DbProvider.Delete<ProjectExtend>(x => x.ProjectID == id1);

                DbProvider.Delete<Project>(x => x.ID == id1);
            }
            DbProvider.SaveChanges();
        }


        //public RepayScheme GetRepaySchemeForProject(int id) {

        //    var project = DbProvider.GetByID<Project>(id);

        //    if(project==null) throw new NullReferenceException("Project不存在或者已经被删除");

        //    var records = DbProvider.D<CreditRepayment>().Where(x => x.ProjectID == id);

        //    IRepayStrategyFactory factory=new RepayStrategyFactory();

        //    var strategy=factory.GetRepayStrategy(project,records.ToList());
                            
        //    return strategy.GetPlanTable(project.LoadMoney);

        //}


        /// <summary>
        /// 发布Project
        /// </summary>
        /// <param name="id"></param>
        /// <param name="startTime">开始时间</param>
        public void Release(int id,DateTime startTime) {

            var project = DbProvider.GetByID<Project>(id);

            if (project == null) throw new NullReferenceException("Project不存在或者已经被删除");

            project.SetApproveStatus(true);

            project.StartTime = startTime;

            DbProvider.SaveChanges();
        }

        /// <summary>
        /// 驳回Project
        /// </summary>
        /// <param name="id"></param>
        /// <param name="remark"></param>
        public void Reject(int id,string remark) {

            var project = DbProvider.GetByID<Project>(id);

            if (project == null) throw new NullReferenceException("Project不存在或者已经被删除");

            project.SetApproveStatus(false,remark);

            DbProvider.SaveChanges();

        }

        /// <summary>
        /// 支付，划款
        /// </summary>
        /// <param name="id"></param>
        /// <param name="start"></param>
        public void Paying(int id,DateTime start) {
            var project = DbProvider.GetByID<Project>(id);

            if (project == null) throw new NullReferenceException("Project不存在或者已经被删除");

            if (start < project.StartTime) throw new NullReferenceException("日期输入错误");

            var borrower = DbProvider.GetByID<User>(project.UserID);

            if(borrower==null) throw new NullReferenceException("借款人不存在或者已经被删除");

            project.SetReplayStatus(start, 0);
            
            borrower.UserAccount.BorrowerOver = true;

            var borrowLog= borrower.Transaction(UserTransLog.TradeType.BorrowMoney, project.LoadMoney, "系统", "得到编号为{0}项目的募集资金".FormatWith(project.ID));
            var remitLog = borrower.Transaction(UserTransLog.TradeType.RemitMoney, -project.LoadMoney, "系统", "提现编号为{0}项目的募集资金".FormatWith(project.ID));

            DbProvider.Add(borrowLog);
            DbProvider.Add(remitLog);

            var strategy = new RepayStrategyFactory().GetRepayStrategy(project);

            var proScheme=strategy.GetRepayTableForProject(new List<DebtorRepayment>());

            project.NextRepayTime = proScheme.FirstStage.Time;
            project.CurrentStage = 0;
            project.TotalStage = proScheme.Stages.Count;

            foreach (var credit in DbProvider.D<Credit>().Where(x=>x.ProjectID==project.ID).ToList()) {
                var scheme = strategy.GetCreditRepaymenScheme(credit);
                credit.NextRepayTime = scheme.FirstStage.Time;
                credit.TotalStage = scheme.Stages.Count;
                credit.WaitRepayEarning = scheme.WaitRepayInterest;
                credit.WaitRepayPrincipal = scheme.WaitRepayPrincipal;
                credit.Status=CreditStatus.Repay;

                var load = DbProvider.GetByID<User>(credit.UserID);

                string creditMsg = "投资了编号为{0}的项目,冻结金扣除.".FormatWith(project.ID);

                var creditLog = load.DeductLockMoney(UserTransLog.TradeType.InvestmentToPay, credit.Money, borrower.UserName, creditMsg);
                DbProvider.Add(creditLog);
            }
            
            DbProvider.SaveChanges();
        }

        /// <summary>
        /// 获得标的资料图片
        /// </summary>
        /// <param name="pid"></param>
        /// <returns></returns>
        public IList<ProjectImage> GetProjectImages(int pid) {
            return DbProvider.D<ProjectImage>().Where(x => x.LoanId == pid).OrderByDescending(x => x.Sort).ThenBy(x=>x.ID).ToList();
        }

        public IList<ProjectImage> GetProjectAgencyImages(int aid)
        {
            return DbProvider.D<ProjectImage>().Where(x => x.AgencyId == aid).OrderByDescending(x => x.Sort).ThenBy(x => x.ID).ToList();
        }

        #endregion
    }
}
